Imports System
Imports System.Text
Imports System.Data
Imports System.Collections.Generic
Imports System.Web
Imports System.IO

Imports Framework

'Collection Class (Customisable half)
Partial Public Class CSpeakerList
        
#Region "Filters"
    Public Function HavingProducts() As CSpeakerList
        Dim list As New CSpeakerList(Me.Count)
        For Each i As CSpeaker In Me
            If i.Products.Active.Count > 0 Then list.Add(i)
        Next
        Return list
    End Function
    Public Function HavingProducts(typeId As Byte) As CSpeakerList
        Dim list As New CSpeakerList(Me.Count)
        For Each i As CSpeaker In Me
            If typeId > 0 Then
                If i.Products.Active.GetByTypeId(typeId).Count > 0 Then list.Add(i)
            Else
                If i.Products.Active.Count > 0 Then list.Add(i)
            End If
        Next
        Return list
    End Function
#End Region

#Region "Aggregation"
#End Region

#Region "Searching (Optional)"
    'Represents a simple search box to search PK and any string columns (add overloads as required, based on the pattern below)
    'e.g. Public Function Search(ByVal nameOrId As String, ) As CSpeakerList
    Public Function Search(ByVal nameOrId As String) As CSpeakerList
        '1. Normalisation
        If IsNothing(nameOrId) Then nameOrId = String.Empty
        nameOrId = nameOrId.Trim.ToLower()
        
        '2. Start with a complete list
        Dim results As CSpeakerList = Me

        '3. Use any available index, such as those generated for fk/bool columns
        'Normal Case - non-unique index (e.g. foreign key)
        'If Integer.MinValue <> foreignKey Then results = results.GetByForeignKey(foreignKey)

        'Special case - unique index (e.g. primary key)
        If Not String.IsNullOrEmpty(nameOrId) Then
            'Dim id As Integer
            'If Integer.TryParse(nameOrId, id) Then
            '    Dim obj As CSpeaker = Me.GetById(id)
            '    If Not IsNothing(obj) Then
            '        results = New CSpeakerList(1)
            '        results.Add(obj)
            '        return results
            '    End If
            'End If
        End If
        
        '4. Exit early if remaining (non-index) filters are blank
        If String.IsNullOrEmpty(nameOrId) Then Return results
        
        '5. Manually search each record using custom match logic, building a shortlist
        Dim shortList As New CSpeakerList
        For Each i As CSpeaker In results
            If Match(nameOrId, i) Then shortList.Add(i)
        Next
        Return shortList
    End Function
    'Manual Searching e.g for string-based columns i.e. anything not indexed (add more params if required)
    Private Function Match(ByVal name As String, ByVal obj As CSpeaker) As Boolean
        If Not String.IsNullOrEmpty(name) Then
            If Not IsNothing(obj.SpeakerName) AndAlso obj.SpeakerName.ToLower().Contains(name) Then Return True
            If Not IsNothing(obj.SpeakerAbout) AndAlso obj.SpeakerAbout.ToLower().Contains(name) Then Return True
            If Not IsNothing(obj.SpeakerContactEmail) AndAlso obj.SpeakerContactEmail.ToLower().Contains(name) Then Return True
            Return False 'If filter is active, reject any items that dont match
        End If
        Return True 'No active filters (should catch this in step #4)
    End Function
#End Region

#Region "Cloning"
    Public Function Clone(ByVal target As CDataSrc) As CSpeakerList ', parentId As Integer) As CSpeakerList
        'No Transaction
        If TypeOf target Is CDataSrcRemote Then Return Clone(target, Nothing) ', parentId)

        'Transaction
        Dim cn As IDbConnection = target.Local.Connection()
        Dim tx As IDbTransaction = cn.BeginTransaction()
        Try
            Clone = Clone(target, tx) ', parentId)
            tx.Commit()
        Catch
            tx.Rollback()
            Throw
        Finally
            cn.Close()
        End Try
    End Function
    Public Function Clone(target as CDataSrc, txOrNull as IDbTransaction) As CSpeakerList ', parentId As Integer) As CSpeakerList
        Dim list As New CSpeakerList(Me.Count)
        For Each i As CSpeaker In Me
            list.Add(i.Clone(target, txOrNull))  ', parentId))    *Child entities must reference the new parent
        Next
        Return list
    End Function
#End Region

#Region "Export to Csv"
    'Web - Need to add a project reference to System.Web, or comment out these two methods
    Public Sub ExportToCsv(ByVal response As HttpResponse)
        ExportToCsv(response, "Speakers.csv")
    End Sub
    Public Sub ExportToCsv(ByVal response As HttpResponse, ByVal fileName As String)
        CDataSrc.ExportToCsv(response, fileName) 'Standard response headers
        Dim sw As New StreamWriter(response.OutputStream)
        ExportToCsv(sw)
        sw.Flush()
        response.End()
    End Sub

    'Non-web
    Public Sub ExportToCsv(ByVal filePath As String)
        Dim sw As New StreamWriter(filePath)
        ExportToCsv(sw)
        sw.Close()
    End Sub

    'Logic
    Protected Sub ExportToCsv(ByVal sw As StreamWriter)
        Dim headings As String() = New String() {"SpeakerId", "SpeakerName", "SpeakerImage", "SpeakerAbout", "SpeakerContactPhone", "SpeakerContactEmail"}
        CDataSrc.ExportToCsv(headings, sw)
        For Each i As CSpeaker In Me
            Dim data As Object() = New Object() {i.SpeakerId, i.SpeakerName, i.SpeakerImage, i.SpeakerAbout, i.SpeakerContactPhone, i.SpeakerContactEmail}
            CDataSrc.ExportToCsv(data, sw)
        Next
    End Sub
#End Region

#Region "Alternative Sort Order (In-Memory Sort)"
    'Public
    Public Function SortByActiveCountDescName() As CSpeakerList
        Dim copy As New CSpeakerList(Me)
        copy.Sort(New CSpeaker_SortByActiveCountDescName)
        Return copy
    End Function

    'Private
    Private Class CSpeaker_SortByActiveCountDescName : Implements IComparer(Of CSpeaker)
        Public Function Compare(ByVal x As CSpeaker, ByVal y As CSpeaker) As Integer Implements IComparer(Of CSpeaker).Compare
            Dim i As Integer = x.ActiveCount.CompareTo(y.ActiveCount) * -1
            If 0 <> i Then Return i
            Return x.SpeakerName.CompareTo(y.SpeakerName)
        End Function
    End Class
#End Region

End Class
